<?php

namespace App\Http\Controllers\Api;

use Exception;
use ReflectionMethod;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;

class ApiBase extends Controller
{
    use \App\MyTrait\MyResponse;
    
    private $isDev= false;
    protected $method = null;
    protected $validateConfig = null;
    protected $validateErr = null;

    public function __construct(){
        $this->isDev = env('APP_IS_DEV');
    }

    private function parseUrl()
    {
        $this->method = \App\Server\Util::routerCamelCase();
        $this->validateConfig = config("validate.{$this->method}");
    }

    private function paramesValidate()
    {
        if ($this->validateConfig) {
            $rules = $this->validateConfig[0];
            $message = $this->validateConfig[1] ?? [];
            $validator = Validator::make(Request()->input(), $rules, $message);
            if ($validator->fails()) {
                $this->validateErr = $validator->errors()->first();
            }
        };
    }

    private function isMyFun()
    {
        return method_exists($this, $this->method);
    }

    public function entry()
    {
        $this->parseUrl();
        $this->paramesValidate();
        try {
            if ($this->validateErr) {
                throw new Exception(json_encode([
                    'error',
                    $this->validateErr, config('api.error.params'),
                ]));
            };
            if (!$this->isMyFun()) {
                throw new Exception(json_encode([
                    'error',
                    ...config('api.error.controllerMethodIsNotExist'),
                ]));
            }
            $ret = $this->{$this->method}(...$this->methodParamsGet());
            return $this->mResponse($ret);
        } catch (Exception $e) {
            if ($this->isDev) {
                return $e->getMessage();
            }
            if ($err = $this->retError(json_decode($e->getMessage(), true))) {
                return $err;
            }
            return $this->mResponse(null, ...config('api.error.server'));
        }
    }

    private function methodParamsGet()
    {
        /**
         * 
         * 处理类型为Class/interface的参数,其他类型过滤掉
         * 
         */
        $params = new ReflectionMethod($this, $this->method);
        $paramsInstanceArr = [];
        foreach ($params->getParameters() as $parameter) {
            $classType = $parameter->getType();
            $paramsInstance = empty($classType) ?
                null : app($classType->getName());
            array_push($paramsInstanceArr, $paramsInstance);
        }
        return $paramsInstanceArr;
    }

    private function retError($ret)
    {
        if (is_array($ret) && isset($ret[0]) && $ret[0] === 'error') {
            array_shift($ret);
            if (count($ret) === 3) {
                array_pop($ret);
                return $this->mResponse(null, ...config('api.error.server'));
            }
            return $this->mResponse(null, ...$ret);
        }
    }

    // 分页
    protected function pageList($query, $fields = ['*'])
    {
        $request = Request()->all();
        $pageSize = $request['pageSize'] ?? 30;
        $page = $request['page'] ?? 1;
        $offset = ($page - 1) * $pageSize;
        $total =  $query->count();
        $list = $query->offset($offset)->limit($pageSize)->get($fields);
        return compact('total', 'list');
    }

    protected function pageListResource($resource, $query, $fields = ['*'])
    {
        $ret = $this->pageList($query, $fields);
        $ret['list'] = $resource::collection($ret['list']);
        return $ret;
    }

    public function __call($name, $args)
    {
        return $this->create([], '数据不存在', 404);
    }
}
